package com.isyscore.os.metadata.common.page;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.isyscore.boot.mybatis.PageRequest;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class PageParamParser<T> {

    public QueryWrapper<T> parsePageParam(PageRequest pageParam) {
        Field[] fields = pageParam.getClass().getDeclaredFields();
        List<ConditionParam> params = null;
        for (Field field : fields) {
            QueryField queryField = field.getAnnotation(QueryField.class);
            if (queryField != null) {
                if (params == null) {
                    params = new ArrayList<ConditionParam>(2);
                }
                ConditionParam param = new ConditionParam();
                param.setName(StrUtil.isEmpty(queryField.name()) ? StrUtil.toUnderlineCase(field.getName()) : queryField.name());
                param.setValue(BeanUtil.getFieldValue(pageParam, field.getName()));
                param.setOperator(queryField.operator());
                params.add(param);
            }
        }
        return buildQueryWrapperFromParams(params);
    }

    public QueryWrapper<T> buildQueryWrapperFromParams(List<ConditionParam> params) {
        QueryWrapper<T> wrapper = new QueryWrapper<T>();
        if (params == null) {
            return wrapper;
        }
        for (ConditionParam param : params) {
            if (param.getValue() == null || StrUtil.isEmpty(param.getValue().toString())) {
                continue;
            }
            switch (param.operator) {
                case EQ:
                    wrapper.eq(param.getName(), param.getValue());
                    break;
                case LIKE:
                    wrapper.like(param.getName(), param.getValue());
                    break;
                case NOT_LIKE:
                    wrapper.notLike(param.getName(), param.getValue());
                    break;
                case NE:
                    wrapper.ne(param.getName(), param.getValue());
                    break;
                case GT:
                    wrapper.gt(param.getName(), param.getValue());
                    break;
                case GE:
                    wrapper.ge(param.getName(), param.getValue());
                    break;
                case LE:
                    wrapper.le(param.getName(), param.getValue());
                    break;
                case LT:
                    wrapper.lt(param.getName(), param.getValue());
                    break;
                case IS_NULL:
                    wrapper.isNull(param.getName());
                    break;
                case IS_NOT_NULL:
                    wrapper.isNotNull(param.getName());
                    break;
                default:
                    break;
            }
        }
        return wrapper;
    }

    @Data
    static class ConditionParam {
        private CompareOperator operator;
        private String name;
        private Object value;
    }
}
